package com.gukun.springboot.tdengine.service.mock;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gukun.springboot.tdengine.dao.DbsMocktaskMapper;
import com.gukun.springboot.tdengine.dao.TDEngineDao;
import com.gukun.springboot.tdengine.domain.common.CommonResult;
import com.gukun.springboot.tdengine.domain.enums.TagType;
import com.gukun.springboot.tdengine.domain.mock.DbsMocktask;
import com.gukun.springboot.tdengine.dto.CreateTableDto;
import com.gukun.springboot.tdengine.dto.DbsMocktaskDto;
import com.gukun.springboot.tdengine.dto.TDengineConfigDto;
import com.gukun.springboot.tdengine.dto.WriteRulesDto;
import com.gukun.springboot.tdengine.pojo.TagData;
import com.gukun.springboot.tdengine.service.TDEngineService;
import com.gukun.springboot.tdengine.service.TDEngineServiceJDBC;
import com.gukun.springboot.tdengine.service.writeplant.FastWriteTagData;
import com.gukun.springboot.tdengine.util.DateUtils;
import com.taosdata.jdbc.ws.TSWSPreparedStatement;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.*;
import java.util.*;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;

@Service
public class DbsMocktaskService {
    @Autowired
    private DbsMocktaskMapper dbsMocktaskMapper;

    @Autowired
    private TDEngineService tdEngineService;
    @Autowired
    private TDEngineServiceJDBC tdEngineServiceJDBC;
    //批量插入执行数据
    public Integer execCount = 0;
    private int maxSQLLength = 1000000;

    /**
     * 新增实时写入任务
     *
     * @param dbsMocktaskDto
     * @return
     */
    public String addTaskInfo(DbsMocktaskDto dbsMocktaskDto) {
        String result = null;
        if (dbsMocktaskDto != null) {
            TDengineConfigDto tDengineConfigDto = dbsMocktaskDto.gettDengineConfigDto();
            if (StringUtils.isBlank(tDengineConfigDto.getName())) {
                return "请先选择数据库名称";
            }
            if (StringUtils.isBlank(tDengineConfigDto.getHost())) {
                return "请先连接数据库";
            }

            if (StringUtils.isBlank(dbsMocktaskDto.getId())) {
                dbsMocktaskDto.setTaskDbname(tDengineConfigDto.getName());
                dbsMocktaskDto.setTaskHost(tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort());
                dbsMocktaskMapper.insert(dbsMocktaskDto);
            } else {
                dbsMocktaskDto.setTaskDbname(tDengineConfigDto.getName());
                dbsMocktaskDto.setTaskHost(tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort());
                dbsMocktaskMapper.updateById(dbsMocktaskDto);
            }
        }
        return result;
    }

    /**
     * 查询任务
     *
     * @param createTableDto
     * @return
     */
    public List<DbsMocktask> searchTaskInfo(CreateTableDto createTableDto) throws SQLException {
        List<DbsMocktask> list = new ArrayList<>();
        TDengineConfigDto tDengineConfigDto = createTableDto.gettDengineConfigDto();
        if (tDengineConfigDto != null && StringUtils.isNotBlank(tDengineConfigDto.getHost()) && StringUtils.isNotBlank(tDengineConfigDto.getName())) {
            LambdaQueryWrapper<DbsMocktask> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DbsMocktask::getTaskDbname, tDengineConfigDto.getName());
            wrapper.eq(DbsMocktask::getTaskHost, tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort());
            list = dbsMocktaskMapper.selectList(wrapper);
            if (list != null && list.size() > 0) {
                TDEngineDao tdEngineDao = tdEngineService.getTDEngineDao(tDengineConfigDto.getHost(), tDengineConfigDto.getPort(),
                        tDengineConfigDto.getUsername(), tDengineConfigDto.getPassword(), tDengineConfigDto.getName());
                tdEngineDao.useDb(tDengineConfigDto.getName());
                for (DbsMocktask dbsMocktask : list) {
                    try {
                        TagData tagData = tdEngineDao.getRealByTableName(dbsMocktask.getTaskPrefix() + dbsMocktask.getStartIndex());
                        if (tagData != null && tagData.getTs() != null) {
                            DateTime dateTime = new DateTime(tagData.getTs());
                            dbsMocktask.setTaskLastwritetime(dateTime);
                        }
                    } catch (Exception e) {
                        dbsMocktask.setTaskLastwritetime(null);
                    }

                }
            }
        }
        return list;
    }

    /**
     * 删除任务
     *
     * @param list
     * @return
     */
    public String deleteTask(List<DbsMocktask> list) {
        if (list != null && list.size() > 0) {
            List<String> idList = new ArrayList<>();
            for (DbsMocktask dbsMocktask : list) {
                idList.add(dbsMocktask.getId());
            }
            dbsMocktaskMapper.deleteBatchIds(idList);
            return "删除成功";
        }
        return "";
    }

    /**
     * 开启任务
     *
     * @param list
     * @return
     */
    public String startTask(List<DbsMocktaskDto> list, WriteRulesDto writeRulesDto) {
        if (list != null && list.size() > 0) {
            for (DbsMocktaskDto dbsMocktaskDto : list) {
                DbsMocktask dto = dbsMocktaskMapper.selectById(dbsMocktaskDto.getId());
                if (!"启动".equalsIgnoreCase(dto.getTaskStatue())) {
                    dto.setTaskStatue("启动");
                    dbsMocktaskMapper.updateById(dto);
                    if (writeRulesDto == null) {
                        writeRulesDto = new WriteRulesDto();
                        CreateTableDto createTableDto = new CreateTableDto();
                        createTableDto.settDengineConfigDto(dbsMocktaskDto.gettDengineConfigDto());
                        createTableDto.setPrefix(dbsMocktaskDto.getTablePre());
                        writeRulesDto.setCreateTableDto(createTableDto);
                    }
                    writeRulesDto.setStartDatetime(null);
                    writeRulesDto.setEndDatetime(null);
                    writeRulesDto.setMockType(Integer.parseInt(dbsMocktaskDto.getTaskMocktype()));
                    writeRulesDto.setPeriod(dto.getTaskPeriod());
                    writeRulesDto.setMnPeriod(dto.getMnPeriod());
                    writeRulesDto.setTableCount(dto.getTaskThread());
                    writeRulesDto.setIndex(dto.getStartIndex().intValue());
                    writeRulesDto.setTableCount(dto.getTaskCount().intValue());
                    if (StringUtils.isNotBlank(dto.getTaskPrefix())) {
                        writeRulesDto.getCreateTableDto().setPrefix(dto.getTaskPrefix());
                    }
                    tdEngineService.beginTDengineWrite(writeRulesDto, dto.getId(), dbsMocktaskDto.getName());
                }
            }
            return "开启任务成功";
        }
        return "";
    }

    /**
     * 关闭任务
     *
     * @param list
     * @return
     */
    public String stopTask(List<DbsMocktaskDto> list, WriteRulesDto writeRulesDto) {
        if (list != null && list.size() > 0) {
            for (DbsMocktaskDto dbsMocktaskDto : list) {
                DbsMocktask dto = dbsMocktaskMapper.selectById(dbsMocktaskDto.getId());
                if (!"停止".equalsIgnoreCase(dto.getTaskStatue())) {
                    dto.setTaskStatue("停止");
                    dbsMocktaskMapper.updateById(dto);
                    if (writeRulesDto == null) {
                        writeRulesDto = new WriteRulesDto();
                        CreateTableDto createTableDto = new CreateTableDto();
                        createTableDto.settDengineConfigDto(dbsMocktaskDto.gettDengineConfigDto());
                        createTableDto.setPrefix(dbsMocktaskDto.getTablePre());
                        writeRulesDto.setCreateTableDto(createTableDto);
                    }
                    writeRulesDto.setMockType(Integer.parseInt(dbsMocktaskDto.getTaskMocktype()));
                    writeRulesDto.setPeriod(dto.getTaskPeriod());
                    writeRulesDto.setTableCount(dto.getTaskThread());
                    writeRulesDto.setIndex(dto.getStartIndex().intValue());
                    writeRulesDto.setTableCount(dto.getTaskCount().intValue());
                    if (StringUtils.isNotBlank(dto.getTaskPrefix())) {
                        writeRulesDto.getCreateTableDto().setPrefix(dto.getTaskPrefix());
                    }
                    tdEngineService.stopTDengineWrite(null, dto.getId());
                }
            }
            return "停止任务成功";
        }
        return "";
    }

    /**
     * 开启全部任务
     *
     * @param writeRulesDto
     * @return
     */
    public String startAllTask(WriteRulesDto writeRulesDto) {
        String result = null;
        TDengineConfigDto tDengineConfigDto = writeRulesDto.getCreateTableDto().gettDengineConfigDto();
        if (writeRulesDto != null && writeRulesDto.getCreateTableDto() != null) {
            if (tDengineConfigDto != null && StringUtils.isNotBlank(tDengineConfigDto.getHost()) && StringUtils.isNotBlank(tDengineConfigDto.getName())) {
                LambdaQueryWrapper<DbsMocktask> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(DbsMocktask::getTaskDbname, tDengineConfigDto.getName());
                wrapper.eq(DbsMocktask::getTaskHost, tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort());
                List<DbsMocktask> list = dbsMocktaskMapper.selectList(wrapper);
                if (list != null && list.size() > 0) {
                    for (DbsMocktask dbsMocktask : list) {
                        DbsMocktask dto = dbsMocktaskMapper.selectById(dbsMocktask.getId());
                        if (!"启动".equalsIgnoreCase(dto.getTaskStatue())) {
                            dto.setTaskStatue("启动");
                            dbsMocktaskMapper.updateById(dto);
                            writeRulesDto.setStartDatetime(null);
                            writeRulesDto.setEndDatetime(null);
                            writeRulesDto.setPeriod(dto.getTaskPeriod());
                            writeRulesDto.setMnPeriod(dto.getMnPeriod());
                            writeRulesDto.setTableCount(dto.getTaskThread());
                            writeRulesDto.setIndex(dto.getStartIndex().intValue());
                            writeRulesDto.setTableCount(dto.getTaskCount().intValue());
                            writeRulesDto.setMockType(Integer.parseInt(dto.getTaskMocktype()));
                            if (StringUtils.isNotBlank(dto.getTaskPrefix())) {
                                writeRulesDto.getCreateTableDto().setPrefix(dto.getTaskPrefix());
                            }
                            tdEngineService.beginTDengineWrite(writeRulesDto, dto.getId(), dbsMocktask.getName());
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * 停止全部任务
     *
     * @param writeRulesDto
     * @return
     */
    public String stopAllTask(WriteRulesDto writeRulesDto) {
        String result = null;
        if (writeRulesDto != null && writeRulesDto.getCreateTableDto() != null) {
            TDengineConfigDto tDengineConfigDto = writeRulesDto.getCreateTableDto().gettDengineConfigDto();
            if (tDengineConfigDto != null && StringUtils.isNotBlank(tDengineConfigDto.getHost()) && StringUtils.isNotBlank(tDengineConfigDto.getName())) {
                LambdaQueryWrapper<DbsMocktask> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(DbsMocktask::getTaskDbname, tDengineConfigDto.getName());
                wrapper.eq(DbsMocktask::getTaskHost, tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort());
                List<DbsMocktask> list = dbsMocktaskMapper.selectList(wrapper);
                if (list != null && list.size() > 0) {
                    for (DbsMocktask dbsMocktask : list) {
                        DbsMocktask dto = dbsMocktaskMapper.selectById(dbsMocktask.getId());
                        if (!"停止".equalsIgnoreCase(dto.getTaskStatue())) {
                            dto.setTaskStatue("停止");
                            dbsMocktaskMapper.updateById(dto);
                            writeRulesDto.setPeriod(dto.getTaskPeriod());
                            writeRulesDto.setTableCount(dto.getTaskThread());
                            writeRulesDto.setIndex(dto.getStartIndex().intValue());
                            writeRulesDto.setTableCount(dto.getTaskCount().intValue());
                            if (StringUtils.isNotBlank(dto.getTaskPrefix())) {
                                writeRulesDto.getCreateTableDto().setPrefix(dto.getTaskPrefix());
                            }
                            tdEngineService.stopTDengineWrite(null, dto.getId());
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * 批量的历史数据写入
     *
     * @param writeRulesDto
     * @return
     */
    public CommonResult<String> batchInsertInfoWrite(WriteRulesDto writeRulesDto) throws Exception {
        this.execCount = 0;
        String result = "";
        if (writeRulesDto != null) {
            CreateTableDto createTableDto = writeRulesDto.getCreateTableDto();
            String tablePrefix = createTableDto.getPrefix();
            TDengineConfigDto tDengineConfigDto = createTableDto.gettDengineConfigDto();
            if (tDengineConfigDto != null) {
                tdEngineServiceJDBC.setDbName(tDengineConfigDto.getName());
                String url = "jdbc:TAOS-RS://" + tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort() + "?batchfetch=true&user="
                        + tDengineConfigDto.getUsername() + "&password=" + tDengineConfigDto.getPassword();
                tdEngineServiceJDBC.setUrl(url);

                Integer tableCount = writeRulesDto.getTableCount();
                Integer startIndex = writeRulesDto.getIndex();
                Integer threadCount = writeRulesDto.getThreadCount();
                Integer mockType = writeRulesDto.getMockType();
                Integer period = writeRulesDto.getPeriod();
                String startTime = writeRulesDto.getStartDatetime();
                String endTime = writeRulesDto.getEndDatetime();
                Integer periodType = writeRulesDto.getPeriodType();

                //查询对应表的父表
                Map<String, List<String>> tableNameMap = tdEngineServiceJDBC.getTableInfo();

                if (tableCount != null && startIndex != null && StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                    Date startDatetime = null;
                    if (StringUtils.isNotBlank(startTime)) {
                        startDatetime = DateUtils.parseDateTime(startTime);
                    }
                    Date endDatetime = null;
                    if (StringUtils.isNotBlank(endTime)) {
                        endDatetime = DateUtils.parseDateTime(endTime);
                    }

                    //存放所有表的数据
                    Map<String, Map<String, List<TagData>>> dataMap = new HashMap<>();
                    //模拟表的索引
                    int tableIndex = 0;
                    for (String stable : tableNameMap.keySet()) {
                        List<String> tables = tableNameMap.get(stable);
                        //模拟表和数据的map
                        Map<String, List<TagData>> map = new HashMap<>();
                        for (String table : tables) {
                            if (tableIndex > tableCount) {
                                break;
                            }
                            if (tableIndex < startIndex) {
                                //跳过前面的表
                                tableIndex++;
                            } else {
                                List<TagData> tags = mockTagData(startDatetime, endDatetime, period,periodType);
                                map.put(table, tags);
                                tableIndex++;
                            }

                        }
                        //模拟表和数据的map
                        dataMap.put(stable, map);
                    }
                    //开始写入数据
                    setValueWithSocket(dataMap, tDengineConfigDto);
                }
            }

        }
        return CommonResult.success(result);
    }

    /**
     * 模拟标签数据
     *
     * @param startDatetime
     * @param endDatetime
     * @param period
     * @return
     */
    private static List<TagData> mockTagData(Date startDatetime, Date endDatetime, Integer period, Integer periodType) {
        int size = 0;
        List<TagData> tags = new ArrayList<>();
        if (startDatetime != null && endDatetime != null) {
            while (!DateUtils.compare(DateUtils.addSecondByN(startDatetime, period * size), endDatetime)) {

                Long startMs = 0L;
                if (periodType == 0) {
                    //固定周期
                   startMs = DateUtils.addSecondByN(startDatetime, period * size).getTime();
                } else {
                    //随机周期
                    startMs = DateUtils.addSecondByN(startDatetime, (period * size - 1)
                            + RandomUtil.getRandom().nextInt(period) + 1).getTime();
                }
                TagData tagData = new TagData();
                tagData.setTs(startMs);
                BigDecimal bigDecimal = new BigDecimal(RandomUtil.getRandom().nextFloat() * 100);
                tagData.setV(bigDecimal.divide(BigDecimal.valueOf(1), 2, RoundingMode.HALF_UP) + "");
                tags.add(tagData);
                size++;
            }
        }
        return tags;
    }

    public int getQueueId(String line, String tablePre, FastWriteTagData fastWriteTagData, String keyNameId) {
//        String suffixNumber = line.substring(0, line.indexOf(',')).split("_")[1]; // For example: TAG_101
        String suffixNumber = line.substring(0, line.indexOf(',')).replace(tablePre, ""); // For example: TAG_101
        return Integer.parseInt(suffixNumber) % fastWriteTagData.getTaskQueues(keyNameId).size();
    }

    /**
     * 判断队列里面是否为空
     *
     * @param list
     * @return
     */
    private boolean checkListIsEmpty(List<BlockingQueue<String>> list) {
        boolean result = true;
        for (BlockingQueue<String> dto : list) {
            if (!dto.isEmpty()) {
                result = false;
                break;
            }
        }
        return result;
    }

    private void setValueWithSocket(Map<String, Map<String, List<TagData>>> tagDataMap, TDengineConfigDto tDengineConfigDto) {
        String url = "jdbc:TAOS-WS://" + tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort()
                + "/" + tDengineConfigDto.getName()
                + "?batchfetch=false&user="
                + tDengineConfigDto.getUsername() + "&password=" + tDengineConfigDto.getPassword();
        try (Connection conn = getConnection(url)) {
            for (String stable : tagDataMap.keySet()) {
                Map<String, List<TagData>> tableDataMap = tagDataMap.get(stable);
                for (String tableName : tableDataMap.keySet()) {
                    String psql = "INSERT INTO ? USING " + tDengineConfigDto.getName() + "." + stable + " TAGS(?,?,?) VALUES(?, ?)";
                    try (TSWSPreparedStatement pst = conn.prepareStatement(psql).unwrap(TSWSPreparedStatement.class)) {
                        pst.execute("use " + tDengineConfigDto.getName());
                        TagType type = null;
                        type = getTagType(type, stable);
                        try {
                            List<TagData> dataList = tableDataMap.get(tableName);
                            if (dataList.size() > 30000) {
                                int index = 0;
                                int size = 30000;
                                while (index * size < dataList.size()) {
                                    List<TagData> tempDataList = new ArrayList<>();
                                    if (index * size + size >= dataList.size()) {
                                        tempDataList = dataList.subList(index * size, dataList.size());
                                    } else {
                                        tempDataList = dataList.subList(index * size, index * size + size);
                                    }
                                    index++;
                                    ArrayList<Long> tss = new ArrayList<>(size);
                                    ArrayList vals = new ArrayList(size);
                                    for (TagData data : tempDataList) {
                                        tss.add(data.getTs());
                                        switch (type) {
                                            case DOUBLE:
                                                vals.add(Double.parseDouble(data.getV()));
                                                break;
                                            case BOOL:
                                                vals.add(Float.parseFloat(data.getV()) > 0);
                                                break;
                                            case INT:
                                                String val = data.getV();
                                                if (val.contains(".")) {
                                                    vals.add(Integer.parseInt(val.split("\\.")[0]));
                                                } else {
                                                    vals.add(Integer.parseInt(val));
                                                }
                                                break;
                                            case FLOAT:
                                                vals.add(Float.parseFloat(data.getV()));
                                                break;
                                        }
                                    }
                                    pst.setTableName(tableName);

                                    // set tags
                                    pst.setTagString(0, "");
                                    pst.setTagString(1, "");
                                    pst.setTagInt(2 ,0);

                                    setTableVal(tableName, pst, type, tss, vals);
                                }
                            } else {
                                ArrayList<Long> tss = new ArrayList<>(10000000);
                                ArrayList vals = new ArrayList(10000000);

                                pst.setTagString(0, "");
                                pst.setTagString(1, "");
                                pst.setTagInt(2 ,0);

                                for (TagData data : dataList) {
                                    tss.add(data.getTs());
                                    switch (type) {
                                        case DOUBLE:
                                            vals.add(Double.parseDouble(data.getV()));
                                            break;
                                        case BOOL:
                                            vals.add(Float.parseFloat(data.getV()) > 0);
                                            break;
                                        case INT:
                                            String val = data.getV();
                                            if (val.indexOf(".") > -1) {
                                                vals.add(Integer.parseInt(val.split("\\.")[0]));
                                            } else {
                                                vals.add(Integer.parseInt(val));
                                            }
                                            break;
                                        case FLOAT:
                                            vals.add(Float.parseFloat(data.getV()));
                                            break;
                                    }
                                }
                                pst.setTableName(tDengineConfigDto.getName() + "." + tableName);
                                setTableVal(tableName, pst, type, tss, vals);
                            }
                            execCount++;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setTableVal(String tableName, TSWSPreparedStatement pst, TagType type, ArrayList<Long> tss, ArrayList vals) throws SQLException {
        pst.setTimestamp(0, tss);
        switch (type) {
            case DOUBLE:
                pst.setDouble(1, vals);
                break;
            case BOOL:
                pst.setBoolean(1, vals);
                break;
            case INT:
                pst.setInt(1, vals);
                break;
            case FLOAT:
                pst.setFloat(1, vals);
                break;
        }
        long start1 = System.currentTimeMillis();
        pst.columnDataAddBatch();
        pst.columnDataExecuteBatch();
        long end1 = System.currentTimeMillis();
        System.out.println(tableName + "插入数据用时: " + (end1 - start1));
    }

    public static TagType getTagType(TagType type, String t) {
        if (t.equalsIgnoreCase("tfloat")) {
            type = TagType.FLOAT;
        } else if (t.equalsIgnoreCase("tdouble")) {
            type = TagType.DOUBLE;
        } else if (t.equalsIgnoreCase("tint")) {
            type = TagType.INT;
        } else if (t.equalsIgnoreCase("tbool")) {
            type = TagType.BOOL;
        }
        return type;
    }

    private void executeSQL(String sql, Statement stmt) throws SQLException {
        try {
            stmt.executeUpdate(sql);
        } catch (SQLException e) {
            int errorCode = e.getErrorCode() & 0xffff;
            if (errorCode == 0x2603) {
                throw e;
            } else {
                throw e;
            }
        } catch (Throwable throwable) {
            throw throwable;
        }
    }

    //    private void setValueWithSocket(Map<String, List<TagData>> tagDataMap, TDengineConfigDto tDengineConfigDto) {
//        String url = "jdbc:TAOS-RS://"+tDengineConfigDto.getHost()+":"+tDengineConfigDto.getPort()+"?batchfetch=true&user="
//                +tDengineConfigDto.getUsername()+"&password="+tDengineConfigDto.getPassword();
//        try (Connection conn = getConnection(url)) {
//            String psql = "INSERT INTO ? VALUES(?, ?)";
//            for (String tagName : tagDataMap.keySet()) {
//                try (TSWSPreparedStatement pst = conn.prepareStatement(psql).unwrap(TSWSPreparedStatement.class)) {
//                    ArrayList<Long> tss = new ArrayList<>(10000000);
//                    ArrayList vals = new ArrayList<>(10000000);
//                    List<TagData> tagDataList = tagDataMap.get(tagName);
//                    for (TagData data : tagDataList) {
//                        tss.add(data.getTs());
//                        vals.add(RandomUtil.getRandom().nextFloat()*100);
//                    }
//                    pst.setTableName(tDengineConfigDto.getName() + "." + tagName);
//                    pst.setTimestamp(0, tss);
//                    pst.setFloat(1,vals);
//                    pst.columnDataAddBatch();
//                    pst.columnDataExecuteBatch();
//                }
//                execCount++;
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//    }
    private Connection getConnection(String url) throws SQLException {
        return DriverManager.getConnection(url);
    }

    /**
     * 实时数据性能查询
     *
     * @param dbsMocktaskDto
     * @return
     */
    public String readRealData(DbsMocktaskDto dbsMocktaskDto) throws SQLException {
        String result = null;
        if (dbsMocktaskDto != null) {
            TDengineConfigDto tDengineConfigDto = dbsMocktaskDto.gettDengineConfigDto();
            String url = "jdbc:TAOS-WS://" + tDengineConfigDto.getHost() + ":" + tDengineConfigDto.getPort() + "?batchfetch=false&user="
                    + tDengineConfigDto.getUsername() + "&password=" + tDengineConfigDto.getPassword();
            try (Connection conn = getConnection(url)) {
                String psql = "select * from (select last_row(*) from " + tDengineConfigDto.getName() + ".tfloat group by ti union all " +
                        "select last_row(*) from " + tDengineConfigDto.getName() + ".tdouble group by ti union all " +
                        "select last_row(*) from " + tDengineConfigDto.getName() + ".tint group by ti union all " +
                        "select last_row(*) from " + tDengineConfigDto.getName() + ".tbool group by ti)  ";

                TSWSPreparedStatement pst = conn.prepareStatement(psql).unwrap(TSWSPreparedStatement.class);
                pst.execute("use " + tDengineConfigDto.getName());
                System.out.println(psql);
                int threadNum = dbsMocktaskDto.getTaskThread();
                long d1 = System.currentTimeMillis();
                if (threadNum == 1) {
                    psql += " limit " + dbsMocktaskDto.getTaskCount() + " offset " + dbsMocktaskDto.getStartIndex();
                    pst.executeQuery(psql);
                    long d2 = System.currentTimeMillis();
                    result = String.valueOf(d2 - d1);
                } else {
                    CountDownLatch latch = new CountDownLatch(threadNum);
                    long size = dbsMocktaskDto.getTaskCount() / threadNum;
                    for (int i = 0; i < threadNum; i++) {
                        int finalI = i;
                        String finalPsql = psql;
                        new Thread(() -> {
                            String val = finalPsql + " limit " + size + " offset " + size * finalI;
                            System.out.println(val);
                            try {
                                pst.executeQuery(val);
                            } catch (SQLException e) {
                                throw new RuntimeException(e);
                            }
                            latch.countDown();
                        }, String.valueOf(i)).start();
                    }
                    latch.await();
                    long endWrite = System.currentTimeMillis();
                    result = String.valueOf(endWrite - d1);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
